﻿
// -----------------------------------------------------------------------------
// --- Page Correct Square --- GBitsetCorrectSquare.h ---
// Подпрограмма коррекции координат букв (квадратиков) в пределах строки.
// -----------------------------------------------------------------------------

void GBitset::CorrectSquare(vector<int> &HBuf,
                            vector<int> &GBuf){


TIME_START

        if( NStrok<0) { return; }


//pagePointDetector
        // Запуск программы предвармтельной вертикальной коррекции квадратиков
                  ////PredvCorrectLetH(HBuf,GBuf);

        // Запуск программы вертикальной коррекции положения квадратиков по верху
                    CorrectLetterH(HBuf,GBuf);

        // Запуск подпрограммы получения координат прямоугольников вокруг точек.
                    SquarePointDetector();

/**/
        // откорректировали координаты квадратиков по горизонтали и вертикали.

if( GrafT[4][0] ) { DM(END);  DM(44444<<" CorrectSquare ");  DM(END); }

TIME_PRINT


}//_____________________________________________________________________________



//  ----------------------------------------------------------------------------
// Запуск программы предвармтельной вертикальной коррекции квадратиков
//  ----------------------------------------------------------------------------

void GBitset::PredvCorrectLetH(vector<int> &HBuf,
                               vector<int> &GBuf){


//  int y,x,p,d,m,n,s0,s1;
//  vector<int> LStr(ncolumns);

                 //   if( NStrok<0) { return; }  page   строка line Line
/*
#ifdef DEBUGLVL
#endif
*/

}//__________________________________________________________________________


//  ----------------------------------------------------------------------------
// Подпрограмма вертикальной коррекции положения квадратиков по верху букв.
//  ----------------------------------------------------------------------------

void GBitset::CorrectLetterH(vector<int> &HBuf,
                             vector<int> &GBuf){

  int y,x,p,d,m,n;
  int y0,y1,x0,x1,s0,s1;
  int DltNstrN,DltNstrNKh,KHigH,KHigHKh,SumA;
  vector<int> BufS(ncolumns);
  

// Подпрограмма вертикальной коррекции положения квадратиков
// (описанных вокруг каждой буквы) по высоте, в пределах строки.
// статистика набирается по верхней полке букв

//TIME_START

       // для визуализации одной строки заремачить цикл по NStrok
       // получение номера строки на графику. Nstr - глобальная.
       // Nstr=3;

//#ifdef PC
//     Nstr=StrToInt(ImageProcessorMain->Edit5->Text);  //
//     if ( Nstr > NStrok ) { Nstr = NStrok; } // NStrok начинается с 1
//#endif
             


// вертикальная коррекция положения квадратиков (описанных вокруг каждой буквы)
// по высоте, в пределах строки Nstr (Nstr - глобальная).
// NStrok=strArray.size(); - вычисленное количество строк в печа

   for ( Nstr=0; Nstr < strArray->size(); Nstr++ ){ // Цикл по количеству строк NStrok
       BufS.assign(ncolumns,0);   GBuf.assign(ncolumns,0);
       // получение координат строк y0, y1 из структуры
       y0=strArray[0][Nstr].y0;   y1=strArray[0][Nstr].y1;
       // получение оптимального коэффициента горизонтальной фильтрации для каждой строки
       DltNstrN = y1 - y0;   DltNstrNKh = DltNstrN*DeltaKh/100;
       KHigH=DltNstrN*2;     KHigHKh=DltNstrNKh*2;  ////

       if ( KHigHKh > 63 ) KHigHKh=63;     if ( KHigHKh < 2 ) KHigHKh=2;
       // выбор области коррекции высоты квадратиков  s1, s0
       s1=y1+(y1-y0)/2;  if ( s1 >= nrows ) {s1=y1-1; s0=y1;}   // верх
       s0=y1-(y1-y0)/3;  if ( s0 <= 0 )     {s1=y1-1; s0=y1;}   // низ

            // получение массова максимумов HBuf для коррекции высоты квадратиков
            for ( y=s0; y < s1; y++ ) { // горизонтальный цикл
                d=y*ncolumns;
                for ( x=0; x < ncolumns; x++ ) { // копирование из bits_data в HBuf
                    HBuf[x]=bits_data[d + x]<<11; // <<11 строки домножены на 2048
                    } // for x
                SP->filterHigh(HBuf,KHigHKh); // сглаживание HBuf ФИЛЬТР НИЗКИХ ЧАСТОТ
                // нахождение max HBuf[x] при движении по y для каждого x
                // порог KHigHKh*8 для маленьких максимумов
                for ( x=0; x < ncolumns; x++ ) { // вертикальный цикл
                    // if( HBuf[x] > BufS[x] ) { BufS[x]=HBuf[x]; GBuf[x]=y; }
                    if( HBuf[x] > BufS[x] && HBuf[x] > KHigHKh<<3 ) {   // <<2
                        BufS[x]=HBuf[x]; GBuf[x]=y;
                    }
// визуализация области коррекции высоты квадратиков (серым)
///                    drawData[0][y][x]*=0.8;      // визуализация //
                    } // for x
            } // for y

            // запись скорректированного по высоте положения квадратиков в структуру
            for ( n=0; n < strArray[0][Nstr].wordArray.size(); n++ ){
                // получение координат квадратиков букв x0,x1, y0,y1 из структуры
                wordOCR *wP=&strArray[0][Nstr].wordArray[n];
                x0 = wP->x0;    x1 = wP->x1;    y0 = wP->y0;    y1 = wP->y1;

                // усреднение адресов в пределах квадратика
                SumA=d=0; // SumA абсолютное (среднее) значение адреса максимума
                for ( m=x0; m < x1; m++ ){
                    if (GBuf[m]<=s1 && GBuf[m]>=s0) {d++; SumA = SumA + GBuf[m];}
                    } // for m
                if ( d == 0 ) { SumA = y1; }  else { SumA=SumA/d + DltNstrN/6; } //
                if ( SumA > s1 || SumA < s0 ) SumA=y1; // микрокоррекция по высоте DltNstrN/5
               /// LineVertical((s1+s0)/2,0x0000AA00);  // вызов рисования зеленый
                    // смещение верхний и нижней граници квадратика
                    strArray[0][Nstr].wordArray[n].y1 = SumA; // верх
                    // проверка соприкосновения с нижней границей печа p < 0
                    p = SumA - (y1 - y0);    if ( p < 0 ) p=y0;
                    strArray[0][Nstr].wordArray[n].y0 = p;    // низ
            } // n

   } // for Nstr // Цикл по количеству строк NStrok

// x0,y0,x1,y1
// x0,y0 координаты левого нижнего угла квадратика строки (слога, буквы).
// x1,y1 координаты правого верхнего угла квадратика строки (слога, буквы).

/**/
#ifdef DEBUGLVL
/*
  // ВИЗУАЛИЗАЦИЯ аналоговая исходных вертикальных сумм в пределах строки (черная)
  int M=2; static short delta=nrows*10/110; //delta=y;
  for(x=0; x < ncolumns; x++) {
  for (y=delta; y<(GBuf[x]/M)+delta; y++)drawData[0][y][x]*=0.4;}// 0.1*ncolumns;
*/

       // Визуализация букв темно синими квадратиками из структур //
//                   wordDraw(0x00AA0011);  // темно синий

//DM(END);  DM(1111<<" correctLetterHH ") DM(DltNstrN<<" DltNstrN ")
//DM(DltNstrNKh<<" DltNstrNKh ")DM(END);
#endif

//TIME_PRINT
/**/

}//_____________________________________________________________________________



//  ----------------------------------------------------------------------------
// Подпрограмма получения координат прямоугольников вокруг точек вдоль строки
//  ----------------------------------------------------------------------------

void GBitset::SquarePointDetector(){


  int y,x,n,s0,s1;
  int x0,x1,x0B,x1B;
  int y0,y1,y0B,y1B;
  int NWord;

//TIME_START


// получение координат прямоугольников (описанных вокруг каждой точки) с учетом Border.
   for ( Nstr=0; Nstr < strArray->size(); Nstr++ ){ // Цикл по количеству строк NStrok

         NWord = strArray[0][Nstr].wordArray.size();
         for ( n=0; n < NWord; n++ ){ // Цикл по количеству квадратиков вдоль строки NWord
          /// получение координат из структуры по x по y

           wordOCR *wP=&strArray[0][Nstr].wordArray[n];
           // x0,x1, y0,y1 координаты квадрата вокруг буквы
           x0 = wP->x0;    x1 = wP->x1;    y0 = wP->y0;    y1 = wP->y1;

           // дополнение прямоугольниками последних букв в строках
           if ( n < NWord-1 ) {
              // x0B,x1B, y0B,y1B координаты квадрата вокруг буквы  Nwrd+1
              wP=&strArray[0][Nstr].wordArray[n+1];
              x0B= wP->x0;    x1B = wP->x1;   y0B = wP->y0;   y1B = wP->y1;
              }
           else { x0B=x0+(x1-x0)*3/2;  x1B=x1+(x1-x0)*3/2;  y0B=y0;  y1B=y1; }


          /// выбор области создания прямоугольников по горизонтали вокруг точек X
             s0 = (x1+x0)/2   + (x1-x0)/4;                  // вправо по x /2/2
             s1 = (x1B+x0B)/2 - (x1B-x0B)/4;                // влево  по x
             //s0 = (x1+x0+x1B+x0B)/4 - (x1-x0)/4   + Brd;  // вправо по x /2/2
             //s1 = (x1+x0+x1B+x0B)/4 + (x1B-x0B)/4 - Brd;  // влево  по x
             // ограничение размера квадратиков при больших расстояниях между буквами
             if ( (x1B+x0B)/2-(x1+x0)/2 > (x1-x0)*3/2 )  { s1=s0 + (x1-x0); }
             // проверка соприкосновения квадратиков с правой границей печа
             if ( s0 > ncolumns ) s0=ncolumns;
             // запись координат квадратиков горизонтали (по x ) в структуру
             strArray[0][Nstr].wordArray[n].xp0 = s0;
             strArray[0][Nstr].wordArray[n].xp1 = s1;
          /// выбор области создания прямоугольников по вертикали вокруг точек Y
             s0 = (y1+y1B)/2 + (y1-y0+y1B-y0B)/12;         // вверх по y /2/5=10
             s1 = (y1+y1B)/2 - (y1-y0+y1B-y0B)*13/50; //11 // вниз  по y /2*2/5=5
             // проверка соприкосновения прямоугольников с верхней границей печа
             if ( s0 > nrows ) s0=nrows;
             // запись координат прямоугольников по вертикали (по y ) в структуру
             strArray[0][Nstr].wordArray[n].yp1 = s0;
             strArray[0][Nstr].wordArray[n].yp0 = s1;

        } // n   // Цикл по количеству квадратиков вдоль строки NWord

   } // for Nstr  // Цикл по количеству строк NStrok

// x0,y0,x1,y1
// x0,y0 координаты левого нижнего угла прямоугольника строки (слога, буквы).
// x1,y1 координаты правого верхнего угла прямоугольника строки (слога, буквы).
// Nstr номер текущей обрабатываемой строки

#ifdef DEBUGLVL
       // Визуализация красными прямоугольниками областей поиска точек  //
//                   pointDraw(0x000000FF);  // красный

/**/
#endif

//TIME_PRINT

/*           // примерный размер точки по x
             strArray[0][Nstr].wordArray[n].xp0 = (sx+sxB)/2 + DltNstrNKh/8;
             strArray[0][Nstr].wordArray[n].xp1 = (sx+sxB)/2 - DltNstrNKh/8;
             // примерный размер точки по y
             strArray[0][Nstr].wordArray[n].yp1 = (y1+y1B)/2 - DltNstrNKh/8;
             strArray[0][Nstr].wordArray[n].yp0 = (y1+y1B)/2 + DltNstrNKh/8;
*/

/// ,Brd, Border=-DltNstrNKh/4; // примерный размер точки по x,y DltNstrNKh*2/8;
// добавление (окантовка вокруг прямоугольников) к  размеру
// прямоугольника, необходимого для работы сглаживающего фильтра Border=0;


}//__________________________________________________________________________


